using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using SKBKontur.Serialization.Helpers;

namespace SKBKontur.Serialization.Binding
{
    public class Utf8StringDictionaryBinder : Binder
    {
        public Utf8StringDictionaryBinder(string indexer)
        {
            Indexer = indexer;
        }

        public string Indexer { get; set; }

        public override void Bind(ref object objectToBind, string propertyName,
                                  Dictionary<string, byte[]> serializedData)
        {
            MethodInfo method = GetPropertySetter(objectToBind, propertyName);
            foreach (var data in serializedData)
            {
                string value = data.Value.ToUtf8Str();
                method.Invoke(objectToBind, new object[] {data.Key, value});
            }
            serializedData.Clear();
        }

        public override void Unbind(object objectToUnbind, string propertyName,
                                    ref Dictionary<string, byte[]> serializedData)
        {
            PropertyInfo propertyInfo = GetPropertyInfo(objectToUnbind, propertyName);
            PropertyInfo indexerInfo = GetPropertyInfo(objectToUnbind, Indexer);
            var keys = (IEnumerable<string>)indexerInfo.GetGetMethod().Invoke(objectToUnbind, new object[0]);
            foreach (string key in keys)
            {
                if (serializedData.ContainsKey(key))
                    throw new SerializationException(string.Format("Key {0} of indexer property {1} has name collision with regular property", key, propertyName));
                serializedData[key] = ((string)propertyInfo.GetGetMethod().Invoke(objectToUnbind, new object[] { key })).ToUtf8ByteArray();
            }
        }

        public override bool IsLast()
        {
            return true;
        }
    }
}